PROGRAMME D'AUTOMATISATION



Bon connaitre le fonctionnement de l'IAT c'est très bien, mais le reverser c'est une autre histoire, le véritable problème c'est pas l'IAT lui-même mais plutôt la reconstruction des différents liens. Comme je l'ai déjà dit, j'avais réalisé un petit programme qui reconstruisait l'IAT et rétablissait les liens les plus communs. Mais faut pas se voiler la face, il est franchement inefficace parce qu'il y a toujours à un moment ou à un autre un type de lien fantaisiste qui fini par faire échouer l'ensemble. Donc l'IAT, ne faîtes pas l'impasse dessus ce serait bien dommage, mais je pense qu'on peut s'en passer en étant un peu plus malin.

Il y a deux grands principes pour appeler une fonction. Soit on l'extrait à partir de l'IAT comme on l'a vue précédemment, soit on a la possibilité de retouver une fonction quelconque en l'appelant à partir des fonctions LoadLibraryA/GetProcAddress.
Le bon point c'est que si vous décidez de reverser un programme, il n'y a aucun problème si LoadLibraryA et GetProcAddress sont présents dans son IAT.
Le mauvais point forcément, c'est que c'est impossible si ces deux fonctions ne sont pas dans son IAT. Et là... Catastrophe... Le tut s'arrête là donc...

Hep!! nan nan... pas si vite!!! Si vous allez sur le site de qui-vous-savez, vous trouverez un programme écrit par y0da. La particularité de ce programme c'est justement de retrouver l'handle de Kernel32 puis les adresses de LoadLibrary et GetProcAddress sans utiliser AUCUNE api. Ouuuu !!! Je sens déjà qu'avant même d'avoir pu lire la suite, votre cerveau commence à bouillonner ... les idées se forment, indistinctes encore, mais une voie se dessine... Ne serait-il pas possible de créer un pseudo-IAT, une nouvelle section recherchant par ses propres moyens les adresses d'éventuelles nouvelles fonctions, et ça uniquement à partir de mnémoniques et rien d'autre ? Bien sûr que c'est possible. Et non seulement c'est faisable, mais c'est FAIT.

Le principe c'est sur un programme cible lui ajouter une nouvelle section, rediriger l'EntryPoint sur elle puis une fois son travail effectué, retourner l'EntryPoint vers son adresse d'origine. Le contenu de cette nouvelle section, c'est ni plus ni moins que le programme de y0da lui-même, ammélioré quelque peu.
Cette section est un véritable programme à part entière. Elle contient à la fois des data et du code.
Mon programme injecte dans la cible le code de y0da et dans sa zone data les noms des fonctions (avec leurs DLL parentes) que vous souhaitez ajouter, et rien d'autre.
Maintenant si vous lancer votre cible, le code de y0da incorporé, va retrouver les noms des fonctions et à partir d'elles il va retrouver leurs adresses dynamiquement. On arrive donc à nos fins, les adresses des nouvelles fonctions deviennent disponibles. Ces adresses sont elles-mêmes ré-inscritent dans la zone data de ma section uniquement si la cible est en route (si vous jetez un coup d'oeil en DeadListing vous ne verrez jamais aucune adresse, elles sont créées et recréées à la volée).
J'ai dit dynamiquement, parce que les adresses retrouvées ne sont pas statiques, et c'est là la grande force de ce principe. Si vous avez une certaine version d'une DLL, l'adresse d'une fonction précise sera valide, et pour cette même DLL mais sous une version plus évolue, l'adresse de la fonction même ayant changée, mon loader retrouvera sa nouvelle adresse. C'est exactement ce qui est fait au niveau d'un vrai IAT. L'énorme avantage, c'est qu'on ne touche absolument pas au véritable IAT et donc aucun lien n'a besoin d'être retouché. Simplement les nouvelles adresses sont mises à part dans la nouvelle section, c'est tout...



Bon, je n'irai pas plus loin. L'utilisation de mon programme est vraiment trivial. Et puisque vous lisez ces lignes, c'est que vous projetez d'ajouter des fonctions à un programme cible, ce qui signifie que vous possédez un niveau suffisament avancé en reverse, donc je ne vous bassinerai pas plus longtemps en vous impossant un exemple. Maintenant, c'est à vous de jouer!

Ah juste deux points avant de nous quitter, GetProcAddress retrouve les adresses des fonctions grâce à leurs noms, donc pour les fonctions exportées BY ORDINAL ne vous étonnez pas si elles refusent de se plier à vos besoins. Mais bon, vous en utilisez souvent vous ?
Egalement, les adresses des nouvelles fonctions ne sont disponibles qu'une fois que ma section aie terminée son travail forcément donc si vous projetez de créer une section de plus pour placer votre propre code, vous devez effecter la redirection vers la vôtre seulement à la fin de la mienne. Mais sachez que ma section est normalement bien suffusante pour y placer aussi le vôtre.

Par Morgatte